﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Bricks.Business.Service.Impl;
using Bricks.Site.Models;
using Bricks.Business.Models.FlowProcess;
using Bricks.Business.Models.Account;
using System.Xml;
using System.Web.Script.Serialization;
using Bricks.Business.Service;
using Bricks.Component.Utils;
using System.Collections;
using Bricks.Site.Web.CommonUtils;
using System.Configuration;
using Bricks.Component.Utils.Extensions;


namespace Bricks.Site.Web.Controllers
{
    [Export]
    public class FlowController : BaseController
    {
        #region 导入服务
        [Import]
        public IFlowNodeService FlowNodeService { get; set; }
        [Import]
        public IBaklogTaskService BaklogTaskService { get; set; }
        [Import]
        public IFlowUtilsService FlowUtilsService { get; set; }
        [Import]
        public IFlowGraphNodeService FlowGraphNodeService { get; set; }
        [Import]
        public ICompleteFlowNodeService CompleteFlowNodeService { get; set; }
        [Import]
        public IProcessedTaskService ProcessedTaskService { get; set; }
        [Import]
        public IFlowProcessMessageService FlowProcessMessageService { get; set; }
        [Import]
        public IBaklogTaskTempService BaklogTaskTempService { get; set; }
        [Import]
        public IHolidayRequestService HolidayRequestService { get; set; }
        [Import]
        public IAlterService AlterService { get; set; }
        [Import]
        public IAlterOrderService AlterOrderService { get; set; }
        [Import]
        public IExpenseService ExpenseService { get; set; }
        [Import]
        public ITotalMaintenanceService TotalMaintenanceService { get; set; }
        [Import]
        public IYearPlanService YearPlanService { get; set; }
        [Import]
        public IMonthPlanService MonthPlanService { get; set; }
        [Import]
        public IStageScheduleService StageScheduleService { get; set; }
        [Import]
        public IEngineeringImageScheduleService EngineeringImageScheduleService { get; set; }
        [Import]
        public IBridgeStatisticsService BridgeStatisticsService { get; set; }
        [Import]
        public ITunnelStatisticsService TunnelStatisticsService { get; set; }
        [Import]
        public ICulvertStatisticsService CulvertStatisticsService { get; set; }
        [Import]
        public ISectionSalaryService SectionSalaryService { get; set; }
        [Import]
        public IOrgInfoService OrgInfoService { get; set; }
        [Import]
        public IUserOrgService UserOrgService { get; set; }
        #endregion

        #region 流转
        /// <summary>
        /// 流转界面的Action：将单据的状态值赋值给CirculationBackView，作为流转视图的Model
        /// </summary>
        /// <param name="flowCode">流程的Code</param>
        /// <param name="recordID">实际单据的ID</param>
        /// <param name="handleState">单据的状态</param>
        /// <returns></returns>
        public ActionResult CirculationFlow(string flowCode, string recordID, string handleState, string currentFlowNodeCode, string processUserDepartment, string processUser)
        {
            FlowRecordView flowRecordView = new FlowRecordView();
            flowRecordView.FlowCode = flowCode;
            flowRecordView.RecordID = recordID;
            flowRecordView.HandleState = handleState;
            flowRecordView.CurrentFlowNodeCode = currentFlowNodeCode;
            flowRecordView.ProcessUserDepartment = processUserDepartment;
            flowRecordView.ProcessUser = processUser;
            return View(flowRecordView);
        }

        [HttpPost]
        public ActionResult SaveCirculationData(FlowRecordView model, string approvalOpinion)
        {
            try
            {
                //获取当前节点
                FlowNodeView currentFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, model.CurrentFlowNodeCode);

                //分析当前节点的XML里面的circulationCell，获取节点Code数组
                string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(currentFlowNodeView.NodeXML, model.RecordID, model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);

                List<FlowNodeView> lstCirculationNode = new List<FlowNodeView>();
                Dictionary<string, List<FlowNodeView>> dicConditionAndCirculationNode = new Dictionary<string, List<FlowNodeView>>();
                //根据第一次获取到的节点数组，获取所有的中间经过的条件节点和流转节点
                foreach (string flowNodeCode in arrFlowNodeCode)
                {
                    List<FlowNodeView> lstConditionAndCirculationNode = new List<FlowNodeView>();
                    GetConditionAndCirculationNode(model.FlowCode, flowNodeCode, model, lstCirculationNode, lstConditionAndCirculationNode);
                    dicConditionAndCirculationNode.Add(flowNodeCode, lstConditionAndCirculationNode);
                }

                //拼接流转节点Code
                string circulationNodeStr = string.Empty;
                foreach (FlowNodeView flowNodeView in lstCirculationNode)
                {
                    circulationNodeStr += flowNodeView.NodeCode + ",";
                }
                circulationNodeStr = circulationNodeStr.Trim(',');

                //处理当前节点
                List<CompleteFlowNodeView> addCompleteFlowNodeList = CompleteFlowNodeService.GetCompleteFlowNode(model.RecordID);
                bool isCompleteCurrentNode = ProcessCurrentNodeForCirculation(addCompleteFlowNodeList, model.RecordID, model.FlowCode, currentFlowNodeView, approvalOpinion, circulationNodeStr);

                //添加流程构造表数据，添加条件节点到节点完成表
                AddFlowGraphNodeAndConditionCompleteFlowNode(dicConditionAndCirculationNode, isCompleteCurrentNode, model.RecordID, currentFlowNodeView.NodeCode, addCompleteFlowNodeList);

                //判断当前节点是否需要生成待办信息
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(currentFlowNodeView.NodeXML);
                bool isGenerateBaklogTask = true;
                XmlNode addBaklogTaskCondition = doc.SelectSingleNode("NodeXML/circulationCell/addBaklogTaskCondition");
                XmlNode baklogTaskConditionExceCondition = doc.SelectSingleNode("NodeXML/circulationCell/addBaklogTaskCondition/execCondition");
                if (addBaklogTaskCondition != null && (baklogTaskConditionExceCondition == null || (baklogTaskConditionExceCondition != null && baklogTaskConditionExceCondition.InnerText == circulationNodeStr)))
                {
                    //如果“判断是否生成待办节点”不为空，“判断是否生成待办的执行条件节点”为空
                    //或者“判断是否生成待办节点”不为空，“判断是否生成待办的执行条件节点”不为空 并且 执行条件的值与当前流转节点列表相等的时候
                    //执行判断是否生成待办节点函数，获取是否需要
                    string functionName = addBaklogTaskCondition.SelectSingleNode("functionName").InnerText;
                    Hashtable para = new Hashtable();
                    para.Add("RecordID", model.RecordID);
                    XmlNode paraNode = addBaklogTaskCondition.SelectSingleNode("functionParam");
                    if (paraNode != null)
                    {
                        para.Add(paraNode.Name, paraNode.InnerText);
                    }
                    isGenerateBaklogTask = Convert.ToBoolean(FlowUtilsService.ExecuteCommand(functionName, para));
                }

                //更新单据,获取申请人
                DateTime requestDate = DateTime.Now;
                if (isCompleteCurrentNode)
                {
                    //需要根据单据的不同相应修改的地方-------------------------------------------------------------------------------------------------
                    requestDate = UpdateReceiptForCirculation(model, lstCirculationNode[0].NodeCode, isGenerateBaklogTask);
                }

                //删除待办,添加待办和流转到的节点的流程数据
                if (isCompleteCurrentNode && isGenerateBaklogTask)
                {
                    int nodelLevel = lstCirculationNode[0].NodeLevel;
                    //删除待办
                    List<BaklogTaskView> originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByRecordID(model.RecordID);
                    List<BaklogTaskView> deleteBaklogTaskNewList = new List<BaklogTaskView>();
                    XmlNode deleteCurrentNodeBaklogTaskCondition = doc.SelectSingleNode("NodeXML/circulationCell/deleteCurrentNodeBaklogTaskCondition");
                    if (deleteCurrentNodeBaklogTaskCondition != null && deleteCurrentNodeBaklogTaskCondition.InnerText == circulationNodeStr)
                    {
                        IEnumerable<BaklogTaskView> deleteList = originalBaklogTaskList.Where(b => b.CurrentFlowNodeCode == model.CurrentFlowNodeCode);
                        foreach (BaklogTaskView baklogTaskView in deleteList)
                        {
                            deleteBaklogTaskNewList.Add(baklogTaskView);
                        }
                    }
                    else
                    {
                        foreach (BaklogTaskView baklogTaskView in originalBaklogTaskList)
                        {
                            if (baklogTaskView.NodeLevel == nodelLevel)
                            {
                                deleteBaklogTaskNewList.Add(baklogTaskView);
                            }
                        }
                    }
                    BaklogTaskService.DeleteBaklogTask(deleteBaklogTaskNewList);

                    //添加待办
                    if (lstCirculationNode[0].NodeCode != "End")
                    {
                        AddBaklogTaskForCirculation(lstCirculationNode, model, requestDate);

                        //需要根据单据的不同相应修改的地方-------------------------------------------------------------------------------------------------
                        AddProcessDataForCirculation(model, lstCirculationNode);
                    }
                    else //如果是end节点的话，删除那些SendState="0"的数据
                    {
                        //需要根据单据的不同相应修改的地方-------------------------------------------------------------------------------------------------
                        DeleteProcessData(model);

                        if (model.FlowCode == "Expense")
                        {
                            ExpenseView expenseView = ExpenseService.GetExpenseByID(model.RecordID);
                            ApprovalExpenseView approvalExpenseView = new ApprovalExpenseView();
                            approvalExpenseView.ID = Guid.NewGuid();
                            approvalExpenseView.ProjectID = expenseView.ProjectID;
                            approvalExpenseView.ContractID = expenseView.ContractID;
                            approvalExpenseView.ExpenseID = expenseView.ExpenseID;
                            approvalExpenseView.ApprovalMoney = expenseView.ApprovalMoney;
                            ExpenseService.InsertApprovalExpense(approvalExpenseView);
                        }

                        AddReviseData(model);

                        FixedCirculated(model);
                    }
                    //返回该值的时候是为了控制撤回按钮能不能用
                    return Content(currentFlowNodeView.NodeCode);
                }
                return Content("发送成功");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        /// <summary>
        /// 根据节点的XML获取流转节点Code
        /// </summary>
        /// <param name="nodeXML">节点的XML</param>
        /// <param name="recordID">单据ID</param>
        /// <returns></returns>
        private string[] GetNodeCodeByXMLForCirculation(string nodeXML, string recordID, string sourceNodeCode, string processUserDepartment, string processUser)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(nodeXML);
            XmlNodeList nodeList = doc.SelectNodes("NodeXML/circulationCell");
            string getType = nodeList[0].SelectSingleNode("getType").InnerText;
            string processNodeCode = string.Empty;
            if (getType.ToLower() == "value")
            {
                processNodeCode = nodeList[0].SelectSingleNode("cellsName").InnerText;
            }
            else
            {
                string functionName = nodeList[0].SelectSingleNode("functionName").InnerText;
                Hashtable para = new Hashtable();
                para.Add("RecordID", recordID);
                para.Add("SourceNodeCode", sourceNodeCode);
                para.Add("ProcessUserDepartment", processUserDepartment);
                para.Add("ProcessUser", processUser);
                XmlNode paraNode = nodeList[0].SelectSingleNode("functionParam");
                if (paraNode != null)
                {
                    para.Add(paraNode.Name, paraNode.InnerText);
                }
                processNodeCode = FlowUtilsService.ExecuteCommand(functionName, para) as string;
            }
            return processNodeCode.Split(',');
        }

        /// <summary>
        /// 获取所有的中间经过的条件节点和流转节点
        /// </summary>
        /// <param name="flowCode">流程编码</param>
        /// <param name="flowNodeCode">流程节点编码</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="dicCirculationNode">记录流转节点的字典</param>
        /// <param name="lstConditionAndCirculationNode">记录条件节点和流转节点的List</param>
        private void GetConditionAndCirculationNode(string flowCode, string flowNodeCode, FlowRecordView model, List<FlowNodeView> lstCirculationNode, List<FlowNodeView> lstConditionAndCirculationNode)
        {
            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, flowNodeCode);
            lstConditionAndCirculationNode.Add(flowNodeView);
            if (flowNodeView.NodeType == 2)
            {
                //如果是条件节点，获取条件节点的XML数据并解析，递归调用
                string[] arrFlowNodeCode = GetNodeCodeByXMLForCirculation(flowNodeView.NodeXML, model.RecordID, model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                foreach (string nextNodeCode in arrFlowNodeCode)
                {
                    GetConditionAndCirculationNode(flowCode, nextNodeCode, model, lstCirculationNode, lstConditionAndCirculationNode);
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(flowNodeView.NodeXML))
                {
                    flowNodeView.DefaultProcessPerson = GetDefaultProcessPerson(flowNodeView.NodeXML, model.ProcessUserDepartment);
                }
                lstCirculationNode.Add(flowNodeView);
            }
        }

        /// <summary>
        /// 获取缺省处理人和部门
        /// </summary>
        /// <param name="docPerson">节点xml文档</param>
        /// <param name="recordID">单据ID</param>
        /// <returns></returns>
        private string GetDefaultProcessPerson(string nodeXML, string processUserDepartment)
        {
            string defaultProcessPerson = string.Empty;
            XmlDocument docPerson = new XmlDocument();
            docPerson.LoadXml(nodeXML);
            XmlNode personNode = docPerson.SelectSingleNode("NodeXML/defaultProcessPerson");
            if (personNode != null)
            {
                string processPersonGetType = personNode.SelectSingleNode("getType").InnerText;
                if (processPersonGetType == "value")
                {
                    defaultProcessPerson = personNode.SelectSingleNode("presonList").InnerText;
                }
                else
                {
                    string functionName = personNode.SelectSingleNode("functionName").InnerText;
                    Hashtable para = new Hashtable();
                    para.Add("OrgCode", processUserDepartment);
                    XmlNode paraNode = personNode.SelectSingleNode("functionParam");
                    if (paraNode != null)
                    {
                        para.Add(paraNode.Name, paraNode.InnerText);
                    }
                    defaultProcessPerson = FlowUtilsService.ExecuteCommand(functionName, para) as string;
                }
            }
            return defaultProcessPerson;
        }

        /// <summary>
        /// 根据当前节点的处理人之间的条件关系来分支；
        /// 如果是and的关系，找到当前处理人所在的待办记录，将其添加到已办表并删除
        /// 如果是空或者是or的关系，找到当前处理人所在的待办记录，将其添加到已办表并删除当前节点的所有待办
        /// 最后判断当前节点在待办里面还有没有记录，没有的话就将当前的状态标记为已完成
        /// </summary>
        /// <param name="addCompleteFlowNodeList">完成节点列表</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="currentFlowNodeView">当前节点信息</param>
        /// <param name="approvalOpinion">审批意见</param>
        /// <param name="circulationNodeStr">流转拼接字符串</param>
        /// <returns></returns>
        private bool ProcessCurrentNodeForCirculation(List<CompleteFlowNodeView> addCompleteFlowNodeList, string recordID, string flowCode, FlowNodeView currentFlowNodeView, string approvalOpinion, string circulationNodeStr)
        {
            bool isComplete = false;
            List<ProcessedTaskView> addProcessedTaskList = new List<ProcessedTaskView>();
            List<BaklogTaskView> deleteBaklogTaskList = new List<BaklogTaskView>();
            List<BaklogTaskView> originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByNodeCode(currentFlowNodeView.NodeCode, recordID);
            List<BaklogTaskTempView> baklogTaskTempList = BaklogTaskTempService.GetBaklogTaskTempByNodeCode(currentFlowNodeView.NodeCode, recordID);

            string handleState = "1";
            if (circulationNodeStr == "End")
            {
                handleState = "2";
            }
            string defaultProcessPersonCondition = string.Empty;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(currentFlowNodeView.NodeXML);
            XmlNode personConditionNode = doc.SelectSingleNode("NodeXML/defaultProcessPerson/condition");
            if (personConditionNode != null)
            {
                defaultProcessPersonCondition = personConditionNode.InnerText;
            }
            if (!string.IsNullOrEmpty(defaultProcessPersonCondition) && defaultProcessPersonCondition.ToLower() == "and")
            {
                BaklogTaskView deleteInfo = originalBaklogTaskList.Find(b => b.CurrentProcessPerson == User.Identity.Name);
                deleteBaklogTaskList.Add(deleteInfo);
                AddProcessedTask(addProcessedTaskList, recordID, flowCode, currentFlowNodeView, approvalOpinion, deleteInfo.CurrentProcessPersonDepartment, deleteInfo.CurrentProcessPerson, handleState);
                AddBaklogTaskTemp(baklogTaskTempList, deleteInfo);
            }
            else
            {
                foreach (BaklogTaskView baklogTaskView in originalBaklogTaskList)
                {
                    deleteBaklogTaskList.Add(baklogTaskView);

                    if (baklogTaskView.CurrentProcessPerson == User.Identity.Name)
                    {
                        AddProcessedTask(addProcessedTaskList, recordID, flowCode, currentFlowNodeView, approvalOpinion, baklogTaskView.CurrentProcessPersonDepartment, baklogTaskView.CurrentProcessPerson, handleState);
                    }
                    AddBaklogTaskTemp(baklogTaskTempList, baklogTaskView);
                }
            }

            BaklogTaskTempService.AddBaklogTaskTemp(baklogTaskTempList);
            BaklogTaskService.DeleteBaklogTask(deleteBaklogTaskList);
            originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByNodeCode(currentFlowNodeView.NodeCode, recordID);
            if (originalBaklogTaskList.Count() == 0)
            {
                AddCompleteFlowNodeForBaklogTask(currentFlowNodeView, circulationNodeStr, baklogTaskTempList, addCompleteFlowNodeList, recordID);
                BaklogTaskTempService.DeleteBaklogTaskTemp(baklogTaskTempList);
                isComplete = true;
            }

            CompleteFlowNodeService.InsetCompleteFlowNode(addCompleteFlowNodeList);
            ProcessedTaskService.AddProcessedTask(addProcessedTaskList);
            return isComplete;
        }

        /// <summary>
        /// 往已办列表添加记录
        /// </summary>
        /// <param name="addProcessedTaskList">已办列表</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="currentFlowNodeView">当前节点信息</param>
        /// <param name="approvalOpinion">审批意见</param>
        /// <param name="currentProcessPersonDepartment">处理人部门</param>
        private void AddProcessedTask(List<ProcessedTaskView> addProcessedTaskList, string recordID, string flowCode, FlowNodeView currentFlowNodeView, string approvalOpinion, string currentProcessPersonDepartment, string currentProcessPerson, string handleState)
        {
            addProcessedTaskList.Add(new ProcessedTaskView()
            {
                ID = Guid.NewGuid(),
                RecordID = recordID,
                FlowCode = flowCode,
                CurrentProcessNodeCode = currentFlowNodeView.NodeCode,
                CurrentProcessNodeName = currentFlowNodeView.NodeName,
                ApprovalOpinion = approvalOpinion,
                CurrentProcessPersonDepartment = OrgInfoService.GetOrgCodeByUserName(User.Identity.Name),//DepartmentPersonUtils.GetDepartmentByUser(User.Identity.Name),
                CurrentProcessPerson = currentProcessPerson,
                ProcessTime = DateTime.Now,
                HandleState = handleState
            });
        }

        /// <summary>
        /// 往待办临时列表添加记录
        /// </summary>
        /// <param name="baklogTaskTempList">待办临时列表</param>
        /// <param name="baklogTaskView">待办记录</param>
        private void AddBaklogTaskTemp(List<BaklogTaskTempView> baklogTaskTempList, BaklogTaskView baklogTaskView)
        {
            baklogTaskTempList.Add(new BaklogTaskTempView()
            {
                ID = baklogTaskView.ID,
                RecordID = baklogTaskView.RecordID,
                CurrentFlowNodeCode = baklogTaskView.CurrentFlowNodeCode,
                CurrentProcessPersonDepartment = baklogTaskView.CurrentProcessPersonDepartment,
                CurrentProcessPerson = baklogTaskView.CurrentProcessPerson
            });
        }

        /// <summary>
        /// 分析待办数据，添加完成节点
        /// </summary>
        /// <param name="currentFlowNodeView">当前节点信息</param>
        /// <param name="circulationNodeStr">流转拼接字符串</param>
        /// <param name="baklogTaskTempList">待办临时列表</param>
        /// <param name="addCompleteFlowNodeList">完成节点列表</param>
        /// <param name="recordID">单据ID</param>
        private void AddCompleteFlowNodeForBaklogTask(FlowNodeView currentFlowNodeView, string circulationNodeStr, List<BaklogTaskTempView> baklogTaskTempList, List<CompleteFlowNodeView> addCompleteFlowNodeList, string recordID)
        {
            //获取完成节点状态：如果节点XML里面的isComplete里面的值不为空并且不等于流转节点拼接字符串的时候，为特殊状态
            int specState = 0;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(currentFlowNodeView.NodeXML);
            XmlNode isCompleteNode = doc.SelectSingleNode("NodeXML/isComplete");
            if (isCompleteNode != null && isCompleteNode.InnerText != circulationNodeStr)
            {
                specState = 1;
            }

            //获取节点的处理部门和人信息
            string nodeProcessDepartmentPerson = string.Empty;
            if (baklogTaskTempList != null)
            {
                foreach (BaklogTaskTempView baklogTaskTempView in baklogTaskTempList)
                {
                    nodeProcessDepartmentPerson += baklogTaskTempView.CurrentProcessPersonDepartment + "|" + baklogTaskTempView.CurrentProcessPerson + ",";
                }
            }

            //获取节点的之前节点Code：如果节点XML里面的NodeXML/preCell/condition的节点值为and，那么之前节点的值就等于它，否则从完成节点里面去匹配
            string preNodeCode = string.Empty;
            XmlNode preNodeList = doc.SelectSingleNode("NodeXML/preCell/cellList");
            XmlNode preNodeCondition = doc.SelectSingleNode("NodeXML/preCell/condition");
            if (preNodeCondition != null && preNodeCondition.InnerText.ToLower() == "and")
            {
                preNodeCode = preNodeList.InnerText;
            }
            else
            {
                if (preNodeList != null)
                {
                    string[] nodeCodeArr = preNodeList.InnerText.Split(',');
                    foreach (string code in nodeCodeArr)
                    {
                        CompleteFlowNodeView completeFlowNodeView = addCompleteFlowNodeList.SingleOrDefault(c => c.NodeCode == code);
                        if (completeFlowNodeView != null)
                        {
                            preNodeCode = completeFlowNodeView.NodeCode;
                        }
                    }
                }
            }

            //获取节点的父节点
            string parentNodeCode = "";
            XmlNode parentNode = doc.SelectSingleNode("NodeXML/parentCell");
            if (parentNode != null)
            {
                parentNodeCode = parentNode.InnerText;
            }

            //如果是分发节点，并且是从子节点返回的时候，分发节点的是真正的完成，只需要更新即可
            if (isCompleteNode != null && isCompleteNode.InnerText == circulationNodeStr)
            {
                List<CompleteFlowNodeView> existsCompleteFlowNodeViewList = CompleteFlowNodeService.GetCompleteFlowNodeByNodeCode(recordID, currentFlowNodeView.NodeCode);
                foreach (CompleteFlowNodeView completeFlowNodeView in existsCompleteFlowNodeViewList)
                {
                    completeFlowNodeView.SpecState = 0;
                }
                CompleteFlowNodeService.UpdateCompleteFlowNode(existsCompleteFlowNodeViewList);
            }
            else
            {
                AddCompleteFlowNode(addCompleteFlowNodeList, recordID, currentFlowNodeView, nodeProcessDepartmentPerson.Trim(','), preNodeCode, parentNodeCode, specState);
            }
        }

        /// <summary>
        /// 往节点完成列表添加记录
        /// </summary>
        /// <param name="addCompleteFlowNodeList">节点完成列表</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="flowNodeView">节点信息</param>
        /// <param name="nodeProcessDepartmentPerson">节点处理部门和人</param>
        /// <param name="preNodeCode">节点的上一个节点</param>
        /// <param name="parentNodeCode">节点的父节点</param>
        /// <param name="specState">特殊状态</param>
        private void AddCompleteFlowNode(List<CompleteFlowNodeView> addCompleteFlowNodeList, string recordID, FlowNodeView flowNodeView, string nodeProcessDepartmentPerson, string preNodeCode, string parentNodeCode, int specState)
        {
            addCompleteFlowNodeList.Add(new CompleteFlowNodeView()
            {
                ID = Guid.NewGuid(),
                RecordID = recordID,
                NodeCode = flowNodeView.NodeCode,
                NodeName = flowNodeView.NodeName,
                NodeProcessDepartmentPerson = nodeProcessDepartmentPerson,
                PreNodeCode = preNodeCode,
                ParentNodeCode = parentNodeCode,
                NodeLevel = flowNodeView.NodeLevel,
                NodeType = flowNodeView.NodeType,
                NodeSubType = flowNodeView.NodeSubType,
                SpecState = specState
            });
        }

        /// <summary>
        /// 添加流程构造表和节点完成表
        /// </summary>
        /// <param name="dicConditionAndCirculationNode">存储所有的中间经过的条件节点和流转节点的字典</param>
        /// <param name="isCompleteCurrentNode">当前节点是否完成</param>
        /// <param name="recordID">单据ID</param>
        /// <param name="nodeCode">当前节点的Code</param>
        /// <param name="addCompleteFlowNodeList">完成节点列表</param>
        private void AddFlowGraphNodeAndConditionCompleteFlowNode(Dictionary<string, List<FlowNodeView>> dicConditionAndCirculationNode, bool isCompleteCurrentNode, string recordID, string nodeCode, List<CompleteFlowNodeView> addCompleteFlowNodeList)
        {
            List<FlowGraphNodeView> addFlowGraphNodeViewList = FlowGraphNodeService.GetFlowGraphNode(recordID);
            foreach (List<FlowNodeView> nodeList in dicConditionAndCirculationNode.Values)
            {
                for (int i = 0; i < nodeList.Count; i++)
                {
                    //判断是否需要将节点添加构造流程表：当节点是流程节点并且当前节点已经完成
                    bool isAdd = true;
                    if ((i == nodeList.Count - 1) && !isCompleteCurrentNode)
                    {
                        isAdd = false;
                    }
                    if (isAdd)
                    {
                        int orderNo = 0;
                        FlowGraphNodeView firstFlowGraphNodeView = addFlowGraphNodeViewList.OrderByDescending(f => f.OrderNo).FirstOrDefault();
                        if (firstFlowGraphNodeView != null)
                        {
                            orderNo = firstFlowGraphNodeView.OrderNo;
                        }
                        string pathStartNodeCode = nodeCode;
                        if (i > 0)
                        {
                            pathStartNodeCode = nodeList[i - 1].NodeCode;
                        }
                        addFlowGraphNodeViewList.Add(new FlowGraphNodeView()
                        {
                            ID = Guid.NewGuid(),
                            RecordID = recordID,
                            PathStartNodeCode = pathStartNodeCode,
                            PathEndNodeCode = nodeList[i].NodeCode,
                            OrderNo = orderNo + 1,
                            NodeType = nodeList[i].NodeType,
                            ActionType = 0
                        });
                    }

                    //添加条件完成节点
                    if (i < nodeList.Count - 1)
                    {
                        string preNodeCode = string.Empty;
                        XmlDocument docConditionNode = new XmlDocument();
                        docConditionNode.LoadXml(nodeList[i].NodeXML);
                        XmlNode preNodeList = docConditionNode.SelectSingleNode("NodeXML/preCell/cellList");
                        string[] nodeCodeArr = preNodeList.InnerText.Split(',');
                        foreach (string code in nodeCodeArr)
                        {
                            CompleteFlowNodeView completeFlowNodeView = addCompleteFlowNodeList.SingleOrDefault(c => c.NodeCode == code);
                            if (completeFlowNodeView != null)
                            {
                                preNodeCode = completeFlowNodeView.NodeCode;
                            }
                        }

                        string parentNodeCode = "";
                        XmlNode parentNode = docConditionNode.SelectSingleNode("NodeXML/parentCell");
                        if (parentNode != null)
                        {
                            parentNodeCode = parentNode.InnerText;
                        }
                        AddCompleteFlowNode(addCompleteFlowNodeList, recordID, nodeList[i], "", preNodeCode, parentNodeCode, 0);
                    }
                }
            }
            FlowGraphNodeService.AddFlowGraphNode(addFlowGraphNodeViewList);
            CompleteFlowNodeService.InsetCompleteFlowNode(addCompleteFlowNodeList);
        }

        /// <summary>
        /// 更新过程数据的状态为流转，将过程数据更新到单据数据，如果流转节点是End并且要生成的话，将单据的状态更新为结束
        /// </summary>
        /// <param name="model">流转的Model</param>
        /// <param name="circulationNode">第一个流转节点</param>
        /// <param name="isGenerateBaklogTask">是够生成待办数据</param>
        private DateTime UpdateReceiptForCirculation(FlowRecordView model, string circulationNode, bool isGenerateBaklogTask)
        {
            DateTime requestDate = DateTime.Now;
            string handleState = "1";
            switch (model.FlowCode)
            {
                case "AlterOne":
                case "AlterTwo":
                case "AlterThree":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    AlterView alterView = AlterService.GetAlterBackupByCondition(model.RecordID, model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                    alterView.HandleState = handleState;
                    alterView.SendState = "1";
                    alterView.LastUpdateTime = DateTime.Now;
                    List<AlterBillView> lstAlterView = AlterService.GetAlterBillBackupList(Guid.Parse(model.RecordID), model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                    foreach (AlterBillView alterBillView in lstAlterView)
                    {
                        alterBillView.SendState = "1";
                        alterBillView.LastUpdateTime = DateTime.Now;
                    }
                    AlterService.SaveAlterBackup(alterView, lstAlterView);
                    AlterService.SaveAlter(alterView, lstAlterView);
                    requestDate = alterView.RequestDate;
                    break;
                case "AlterOrderOne":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderBackupByCondition(model.RecordID, model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                    alterOrderView.HandleState = handleState;
                    alterOrderView.SendState = "1";
                    alterOrderView.LastUpdateTime = DateTime.Now;
                    List<AlterOrderBillView> lstAlterOrderView = AlterOrderService.GetAlterOrderBillBackupList(Guid.Parse(model.RecordID), model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                    foreach (AlterOrderBillView alterOrderBillView in lstAlterOrderView)
                    {
                        alterOrderBillView.SendState = "1";
                        alterOrderBillView.LastUpdateTime = DateTime.Now;
                    }
                    AlterOrderService.SaveAlterOrderBackup(alterOrderView, lstAlterOrderView);
                    AlterOrderService.SaveAlterOrder(alterOrderView, lstAlterOrderView);
                    requestDate = alterOrderView.RequestDate;
                    break;
                case "Expense":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    ExpenseView expenseView = ExpenseService.GetExpenseBackupByCondition(model.RecordID, model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                    expenseView.HandleState = handleState;
                    expenseView.SendState = "1";
                    expenseView.LastUpdateTime = DateTime.Now;

                    List<ConstructionContractEepenseBillView> saveList = new List<ConstructionContractEepenseBillView>();
                    if (expenseView.ContractSource == "Construction")
                    {
                        List<ConstructionContractEepenseBillView> lstConstructionContractEepenseBillView = ExpenseService.GetBillBackupList(Guid.Parse(model.RecordID), model.CurrentFlowNodeCode, model.ProcessUserDepartment, model.ProcessUser);
                        foreach (ConstructionContractEepenseBillView constructionContractEepenseBillView in lstConstructionContractEepenseBillView)
                        {
                            constructionContractEepenseBillView.SendState = "1";
                            constructionContractEepenseBillView.LastUpdateTime = DateTime.Now;
                            saveList.Add(constructionContractEepenseBillView);
                        }
                    }
                    ExpenseService.SaveExpenseBackup(expenseView, saveList);
                    ExpenseService.SaveExpense(expenseView, saveList);
                    requestDate = expenseView.RequestDate;
                    break;
                case "TotalMaintenance":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    TotalMaintenanceView totalMaintenanceView = TotalMaintenanceService.GetTotalMaintenanceByID(model.RecordID.ToGuid());
                    totalMaintenanceView.HandleState = handleState;
                    totalMaintenanceView.SaveState = "0";
                    totalMaintenanceView.LastUpdateTime = DateTime.Now;
                    TotalMaintenanceService.SaveTotalMaintenance(totalMaintenanceView, new List<TotalMaintenanceDetailsView>(), false);
                    requestDate = totalMaintenanceView.RequestDate;
                    break;
                case "YearPlan":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    YearPlanView yearPlanView = YearPlanService.GetYearPlanByID(model.RecordID.ToGuid());
                    yearPlanView.HandleState = handleState;
                    yearPlanView.SaveState = "0";
                    yearPlanView.LastUpdateTime = DateTime.Now;
                    YearPlanService.SaveYearPlan(yearPlanView, new List<YearPlanDetailsView>(), false);
                    requestDate = yearPlanView.RequestDate;
                    break;
                case "MonthPlan":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    MonthPlanView monthPlanView = MonthPlanService.GetMonthPlanByID(model.RecordID.ToGuid());
                    monthPlanView.HandleState = handleState;
                    monthPlanView.SaveState = "0";
                    monthPlanView.LastUpdateTime = DateTime.Now;
                    MonthPlanService.SaveMonthPlan(monthPlanView, new List<MonthPlanDetailsView>(), false);
                    requestDate = monthPlanView.RequestDate;
                    break;
                case "StageSchedule":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    StageScheduleView stageScheduleView = StageScheduleService.GetStageScheduleByID(model.RecordID.ToGuid());
                    stageScheduleView.HandleState = handleState;
                    stageScheduleView.SaveState = "0";
                    stageScheduleView.LastUpdateTime = DateTime.Now;
                    StageScheduleService.SaveStageSchedule(stageScheduleView, new List<StageScheduleDetailsView>(), false);
                    requestDate = stageScheduleView.RequestDate;
                    break;
                case "SectionSalary":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    SectionSalaryView sectionSalaryView = SectionSalaryService.GetSectionSalaryByID(model.RecordID.ToGuid());
                    sectionSalaryView.HandleState = handleState;
                    sectionSalaryView.SaveState = "0";
                    sectionSalaryView.LastUpdateTime = DateTime.Now;
                    SectionSalaryService.SaveSectionSalary(sectionSalaryView, new List<SectionSalaryDetailsView>(), false);
                    requestDate = sectionSalaryView.RequestDate;
                    break;
                case "EngineeringImageSchedule":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    EngineeringImageScheduleView engineeringImageScheduleView = EngineeringImageScheduleService.GetEngineeringImageScheduleByID(model.RecordID.ToGuid());
                    engineeringImageScheduleView.HandleState = handleState;
                    engineeringImageScheduleView.SaveState = "0";
                    engineeringImageScheduleView.LastUpdateTime = DateTime.Now;
                    EngineeringImageScheduleService.SaveEngineeringImageSchedule(engineeringImageScheduleView, new List<EngineeringImageScheduleDetailsView>(), false);
                    requestDate = engineeringImageScheduleView.RequestDate;
                    break;
                case "BridgeStatistics":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    BridgeStatisticsView bridgeStatisticsView = BridgeStatisticsService.GetBridge(model.RecordID.ToGuid());
                    bridgeStatisticsView.HandleState = handleState;
                    bridgeStatisticsView.SaveState = "0";
                    bridgeStatisticsView.LastUpdateTime = DateTime.Now;
                    BridgeStatisticsService.Save(bridgeStatisticsView, new List<BridgeStatisticsDetailView>(), false);
                    requestDate = bridgeStatisticsView.RequestDate;
                    break;
                case "TunnelStatistics":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    TunnelStatisticsView tunnelStatistics = TunnelStatisticsService.GetTunnel(model.RecordID.ToGuid());
                    tunnelStatistics.HandleState = handleState;
                    tunnelStatistics.SaveState = "0";
                    tunnelStatistics.LastUpdateTime = DateTime.Now;
                    TunnelStatisticsService.Save(tunnelStatistics, new List<TunnelStatisticsDetailView>(), false);
                    requestDate = tunnelStatistics.RequestDate;
                    break;
                case "CulvertStatistics":
                    if (isGenerateBaklogTask && circulationNode == "End")
                    {
                        handleState = "2";
                    }
                    CulvertStatisticsView culvertStatisticsView = CulvertStatisticsService.GetCulvert(model.RecordID.ToGuid());
                    culvertStatisticsView.HandleState = handleState;
                    culvertStatisticsView.SaveState = "0";
                    culvertStatisticsView.LastUpdateTime = DateTime.Now;
                    CulvertStatisticsService.Save(culvertStatisticsView, new List<CulvertStatisticsDetailView>(), false);
                    requestDate = culvertStatisticsView.RequestDate;
                    break;
            }
            return requestDate;
        }

        /// <summary>
        /// 添加待办
        /// </summary>
        /// <param name="lstCirculationNode">流转节点列表</param>
        /// <param name="model">model</param>
        /// <param name="requestPerson">申请人</param>
        private void AddBaklogTaskForCirculation(List<FlowNodeView> lstCirculationNode, FlowRecordView model, DateTime requestDate)
        {
            List<BaklogTaskView> addList = new List<BaklogTaskView>();
            foreach (FlowNodeView circulationNode in lstCirculationNode)
            {
                string[] processDepartmentAndPersonArr = circulationNode.DefaultProcessPerson.Split(',');
                foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                {
                    string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                    BaklogTaskView add = new BaklogTaskView();
                    add.ID = GuidHelper.NewGuid();
                    add.RecordID = model.RecordID;
                    add.TaskType = model.FlowCode;
                    add.RequestDate = requestDate;
                    add.CurrentFlowNodeCode = circulationNode.NodeCode;
                    add.CurrentProcessPersonDepartment = subProcessDepartmentAndPersonArr[0];
                    add.CurrentProcessPerson = subProcessDepartmentAndPersonArr[1];
                    add.NodeLevel = circulationNode.NodeLevel;
                    addList.Add(add);
                }
            }
            BaklogTaskService.AddBaklogTask(addList);
        }

        /// <summary>
        /// 添加过程数据
        /// </summary>
        /// <param name="model">model</param>
        /// <param name="lstCirculationNode">流转节点列表</param>
        private void AddProcessDataForCirculation(FlowRecordView model, List<FlowNodeView> lstCirculationNode)
        {
            switch (model.FlowCode)
            {
                case "AlterOne":
                case "AlterTwo":
                case "AlterThree":
                    AlterView alterView = AlterService.GetAlterByID(model.RecordID);
                    List<AlterBillView> lstAlterBillView = AlterService.GetAlterBillList(Guid.Parse(model.RecordID));
                    foreach (FlowNodeView circulationNode in lstCirculationNode)
                    {
                        string[] processDepartmentAndPersonArr = circulationNode.DefaultProcessPerson.Split(',');
                        foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                        {
                            string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                            alterView.ID = GuidHelper.NewGuid();
                            alterView.AssociatedNodeCode = circulationNode.NodeCode;
                            alterView.LastUpdateUserDepartment = subProcessDepartmentAndPersonArr[0];
                            alterView.LastUpdateUser = subProcessDepartmentAndPersonArr[1];
                            alterView.LastUpdateTime = DateTime.Now;
                            //alterView.SourceNodeCode = model.CurrentFlowNodeCode;
                            //alterView.SourceUserDepartment = model.ProcessUserDepartment;
                            //alterView.SourceUser = model.ProcessUser;
                            alterView.SaveState = "0";
                            alterView.SendState = "0";
                            foreach (AlterBillView alterBillView in lstAlterBillView)
                            {
                                alterBillView.ID = GuidHelper.NewGuid();
                                alterBillView.AssociatedNodeCode = circulationNode.NodeCode;
                                alterBillView.LastUpdateUserDepartment = subProcessDepartmentAndPersonArr[0];
                                alterBillView.LastUpdateUser = subProcessDepartmentAndPersonArr[1];
                                alterBillView.LastUpdateTime = DateTime.Now;
                                alterBillView.SendState = "0";
                            }
                            AlterService.SaveAlterBackup(alterView, lstAlterBillView);
                        }
                    }
                    break;
                case "AlterOrderOne":
                    AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderByID(model.RecordID);
                    List<AlterOrderBillView> lstAlterOrderBillView = AlterOrderService.GetAlterOrderBillList(Guid.Parse(model.RecordID));
                    foreach (FlowNodeView circulationNode in lstCirculationNode)
                    {
                        string[] processDepartmentAndPersonArr = circulationNode.DefaultProcessPerson.Split(',');
                        foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                        {
                            string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                            alterOrderView.ID = GuidHelper.NewGuid();
                            alterOrderView.AssociatedNodeCode = circulationNode.NodeCode;
                            alterOrderView.LastUpdateUserDepartment = subProcessDepartmentAndPersonArr[0];
                            alterOrderView.LastUpdateUser = subProcessDepartmentAndPersonArr[1];
                            alterOrderView.LastUpdateTime = DateTime.Now;
                            alterOrderView.SaveState = "0";
                            alterOrderView.SendState = "0";
                            foreach (AlterOrderBillView alterOrderBillView in lstAlterOrderBillView)
                            {
                                alterOrderBillView.ID = GuidHelper.NewGuid();
                                alterOrderBillView.AssociatedNodeCode = circulationNode.NodeCode;
                                alterOrderBillView.LastUpdateUserDepartment = subProcessDepartmentAndPersonArr[0];
                                alterOrderBillView.LastUpdateUser = subProcessDepartmentAndPersonArr[1];
                                alterOrderBillView.LastUpdateTime = DateTime.Now;
                                alterOrderBillView.SendState = "0";
                            }
                            AlterOrderService.SaveAlterOrderBackup(alterOrderView, lstAlterOrderBillView);
                        }
                    }
                    break;
                case "Expense":
                    ExpenseView expenseView = ExpenseService.GetExpenseByID(model.RecordID);
                    List<ConstructionContractEepenseBillView> saveList = new List<ConstructionContractEepenseBillView>();
                    if (expenseView.ContractSource == "Construction")
                    {
                        saveList = ExpenseService.GetBillList(Guid.Parse(model.RecordID));
                    }
                    foreach (FlowNodeView circulationNode in lstCirculationNode)
                    {
                        string[] processDepartmentAndPersonArr = circulationNode.DefaultProcessPerson.Split(',');
                        foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                        {
                            string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                            expenseView.ID = GuidHelper.NewGuid();
                            expenseView.AssociatedNodeCode = circulationNode.NodeCode;
                            expenseView.LastUpdateUserDepartment = subProcessDepartmentAndPersonArr[0];
                            expenseView.LastUpdateUser = subProcessDepartmentAndPersonArr[1];
                            expenseView.LastUpdateTime = DateTime.Now;
                            expenseView.SaveState = "0";
                            expenseView.SendState = "0";
                            foreach (ConstructionContractEepenseBillView constructionContractEepenseBillView in saveList)
                            {
                                constructionContractEepenseBillView.ID = GuidHelper.NewGuid();
                                constructionContractEepenseBillView.AssociatedNodeCode = circulationNode.NodeCode;
                                constructionContractEepenseBillView.LastUpdateUserDepartment = subProcessDepartmentAndPersonArr[0];
                                constructionContractEepenseBillView.LastUpdateUser = subProcessDepartmentAndPersonArr[1];
                                constructionContractEepenseBillView.LastUpdateTime = DateTime.Now;
                                constructionContractEepenseBillView.SendState = "0";
                            }
                            ExpenseService.SaveExpenseBackup(expenseView, saveList);
                        }
                    }
                    break;
            }
        }

        /// <summary>
        /// 流程流转完成之后删除没有发送的过程数据
        /// </summary>
        /// <param name="model"></param>
        private void DeleteProcessData(FlowRecordView model)
        {
            switch (model.FlowCode)
            {
                case "AlterOne":
                case "AlterTwo":
                case "AlterThree":
                    AlterService.DeleteAlterProcessData(model.RecordID);
                    break;
                case "AlterOrderOne":
                    AlterOrderService.DeleteAlterOrderProcessData(model.RecordID);
                    break;
                case "Expense":
                    ExpenseService.DeleteExpenseProcessData(model.RecordID);
                    break;
            }
        }

        /// <summary>
        /// 添加修订数据
        /// </summary>
        /// <param name="model"></param>
        private void AddReviseData(FlowRecordView model)
        {
            switch (model.FlowCode)
            {
                case "TotalMaintenance":
                    TotalMaintenanceService.AddReviseData(model.RecordID.ToGuid());
                    break;
                case "YearPlan":
                    YearPlanService.AddReviseData(model.RecordID.ToGuid());
                    break;
            }
        }

        /// <summary>
        /// 流程盘完固定传阅
        /// </summary>
        /// <param name="model"></param>
        private void FixedCirculated(FlowRecordView model)
        {
            List<FlowProcessMessageView> lstFlowProcessMessageView = new List<FlowProcessMessageView>();
            string fixedCirculatedDepartmentAndUserStr = string.Empty;
            switch (model.FlowCode)
            {
                case "AlterOne":
                case "AlterTwo":
                case "AlterThree":
                    AlterView alterView = AlterService.GetAlterByID(model.RecordID);
                    if (alterView != null)
                    {
                        if (alterView.AlterType == "一般")
                        {
                            fixedCirculatedDepartmentAndUserStr = ConfigurationManager.AppSettings["CommonAlterEndCirculated"] as string;
                        }
                        else if (alterView.AlterType == "较大")
                        {
                            fixedCirculatedDepartmentAndUserStr = ConfigurationManager.AppSettings["SignificantAlterEndCirculated"] as string;
                        }
                    }
                    break;
                case "Expense":
                    //获取拨付款固定传阅
                    fixedCirculatedDepartmentAndUserStr = ConfigurationManager.AppSettings["ExpenseEndCirculated"] as string;
                    break;
            }
            string[] fixedCirculatedDepartmentAndUserArr = fixedCirculatedDepartmentAndUserStr.Split(',');
            foreach (string fixedCirculatedDepartmentAndUser in fixedCirculatedDepartmentAndUserArr)
            {
                string[] departmentAndUserArr = fixedCirculatedDepartmentAndUser.Split('|');
                lstFlowProcessMessageView.Add(new FlowProcessMessageView()
                {
                    ID = GuidHelper.NewGuid(),
                    RecordID = model.RecordID,
                    FlowCode = model.FlowCode,
                    FlowNodeCode = model.CurrentFlowNodeCode,
                    ProcessUserDepartment = departmentAndUserArr[0],
                    ProcessUser = departmentAndUserArr[1],
                    SponsorUser = User.Identity.Name,
                    ProcessType = "1",
                    LastUpdateUser = User.Identity.Name,
                    LastUpdateTime = DateTime.Now
                });
            }
            FlowProcessMessageService.AddFlowProcessMessage(lstFlowProcessMessageView);
        }
        #endregion

        #region 传阅
        public ActionResult CirculatedFlow(string flowCode, string recordID, string nodeCode, string department)
        {
            FlowRecordView flowRecordView = new FlowRecordView();
            flowRecordView.RecordID = recordID;
            flowRecordView.FlowCode = flowCode;
            flowRecordView.CurrentFlowNodeCode = nodeCode;
            flowRecordView.ProcessUserDepartment = department;
            return View(flowRecordView);
        }

        public ActionResult SetFlowCirculatedData(string orgCode)
        {
            List<OrgUserView> lstOrgUserView = new List<OrgUserView>();
            OrgInfo orgInfo = OrgInfoService.Orgs.SingleOrDefault(O => O.OrgCode == orgCode);
            if (orgInfo != null)
            {
                GetOrgAndUser(lstOrgUserView, orgInfo, "");
            }
            return Json(lstOrgUserView);
        }

        private void GetOrgAndUser(List<OrgUserView> lstOrgUserView, OrgInfo orgInfo, string pCode)
        {
            lstOrgUserView.Add(new OrgUserView() { id = orgInfo.OrgCode, text = orgInfo.OrgName, parent = pCode });
            var lstUserInfo = from userInfo in UserInfoService.Users
                              join orgUser in UserOrgService.UserOrgs on userInfo.ID equals orgUser.UserID
                              where orgUser.OrgID == orgInfo.ID && userInfo.UserName != User.Identity.Name
                              select new { userInfo.UserName, userInfo.RealName, orgInfo.OrgCode };
            foreach (var userInfo in lstUserInfo)
            {
                OrgUserView orgUserView = new OrgUserView();
                orgUserView.id = userInfo.UserName;
                orgUserView.text = userInfo.RealName;
                orgUserView.parent = userInfo.OrgCode;
                orgUserView.attributes.type = "1";
                lstOrgUserView.Add(orgUserView);
            }
            IQueryable<OrgInfo> lstSubOrgCode = OrgInfoService.Orgs.Where(o => o.PID == orgInfo.ID);
            foreach (OrgInfo subOrgInfo in lstSubOrgCode)
            {
                GetOrgAndUser(lstOrgUserView, subOrgInfo, orgInfo.OrgCode);
            }
        }

        [HttpPost]
        public ActionResult SaveCirculatedData(FlowRecordView model, string orgCodeAndUserNameStr)
        {
            try
            {
                List<FlowProcessMessageView> addList = new List<FlowProcessMessageView>();
                string[] orgCodeAndUserNameArr = orgCodeAndUserNameStr.Split(',');
                foreach (string orgCodeAndUserName in orgCodeAndUserNameArr)
                {
                    string[] subOrgCodeAndUserNameArr = orgCodeAndUserName.Split('|');
                    addList.Add(new FlowProcessMessageView()
                    {
                        ID = GuidHelper.NewGuid(),
                        RecordID = model.RecordID,
                        FlowCode = model.FlowCode,
                        FlowNodeCode = model.CurrentFlowNodeCode,
                        ProcessUserDepartment = subOrgCodeAndUserNameArr[0],
                        ProcessUser = subOrgCodeAndUserNameArr[1],
                        SponsorUser = User.Identity.Name,
                        ProcessType = "1",
                        LastUpdateUser = User.Identity.Name,
                        LastUpdateTime = DateTime.Now
                    });
                }
                FlowProcessMessageService.AddFlowProcessMessage(addList);
                return Content("传阅成功");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }
        #endregion

        #region 已阅
        public ActionResult ReceiptFlow(string flowCode, string messageID)
        {
            FlowRecordView flowRecordView = new FlowRecordView();
            flowRecordView.FlowCode = flowCode;
            flowRecordView.MessageID = messageID;
            return View(flowRecordView);
        }

        [HttpPost]
        public ActionResult SaveReceiptData(FlowRecordView model, string approvalOpinion)
        {
            try
            {
                FlowProcessMessageView flowProcessMessageView = FlowProcessMessageService.GetFlowProcessMessageByID(Guid.Parse(model.MessageID));
                flowProcessMessageView.ProcessType = "2";
                flowProcessMessageView.ApprovalOpinion = approvalOpinion;
                flowProcessMessageView.LastUpdateUser = User.Identity.Name;
                flowProcessMessageView.LastUpdateTime = DateTime.Now;
                FlowProcessMessageService.UpdateFlowProcessMessage(flowProcessMessageView);
                return Content("已阅成功");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }
        #endregion

        #region 回退
        /// <summary>
        /// 回退界面的Action：将单据的状态值赋值给CirculationBackView，作为回退视图的Model
        /// </summary>
        /// <param name="flowCode"></param>
        /// <param name="recordID"></param>
        /// <returns></returns>
        public ActionResult BackFlow(string flowCode, string recordID, string flowNodeCode)
        {
            FlowRecordView backView = new FlowRecordView();
            backView.RecordID = recordID;
            backView.FlowCode = flowCode;
            backView.CurrentFlowNodeCode = flowNodeCode;
            return View(backView);
        }

        public ActionResult SetFlowBackData(string flowCode, string recordID, string currentProcessNodeCode)
        {
            return Json(GetBackNodeList(flowCode, recordID, currentProcessNodeCode, false), JsonRequestBehavior.AllowGet);
        }

        private List<CompleteFlowNodeView> GetBackNodeList(string flowCode, string recordID, string currentProcessNodeCode, bool isDesc = true)
        {
            FlowNodeView currentFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, currentProcessNodeCode);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(currentFlowNodeView.NodeXML);
            string parentNodeCode = "";
            XmlNode parentNode = doc.SelectSingleNode("NodeXML/parentCell");
            if (parentNode != null)
            {
                parentNodeCode = parentNode.InnerText;
            }
            return CompleteFlowNodeService.GetCompleteFlowNodeByParentNodeCode(recordID, parentNodeCode, true, isDesc);
        }

        [HttpPost]
        public ActionResult SaveBackData(FlowRecordView model, string backNodeListJson, string approvalOpinion)
        {
            try
            {
                //转换回退节点成XML,获取要回退节点信息
                backNodeListJson = "{\"rows\":" + backNodeListJson + "}";
                XmlNodeList selectBackNodeList = XMLJsonUtils.JsonToXml(backNodeListJson).SelectNodes("root/rows/Item");
                string backNodeCode = selectBackNodeList[0].SelectSingleNode("NodeCode").InnerText;
                FlowNodeView backFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, backNodeCode);

                //处理当前节点:删待办，加已办
                FlowNodeView currentFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, model.CurrentFlowNodeCode);
                ProcessCurrentNodeForBack(model, approvalOpinion, currentFlowNodeView);

                //分析回退到的节点信息，获取and关系的并行节点
                XmlDocument docBack = new System.Xml.XmlDocument();
                docBack.LoadXml(backFlowNodeView.NodeXML);
                string andNodeCodeStr = GetBrotherNodeCode(docBack, "NodeXML/brotherCell/andCellList");
                string[] excludeNodeCodeArr = andNodeCodeStr.Split(',');

                //获取回退经过的节点，必须将与回退到的节点是and关系的兄弟节点排除掉
                List<CompleteFlowNodeView> backNodeList = GetBackNodeList(model.FlowCode, model.RecordID, model.CurrentFlowNodeCode);
                List<CompleteFlowNodeView> backPassCodeList = new List<CompleteFlowNodeView>();
                foreach (CompleteFlowNodeView completeFlowNodeView in backNodeList)
                {
                    if (!excludeNodeCodeArr.Contains(completeFlowNodeView.NodeCode))
                    {
                        backPassCodeList.Add(completeFlowNodeView);
                    }
                    if (completeFlowNodeView.NodeCode == backNodeCode)
                    {
                        break;
                    }
                }

                //给中间节点发回退消息
                int actionType = AddFlowProcessMessage(backPassCodeList, model.FlowCode, backNodeCode);

                //构造回退流程写入流程节点表
                List<BackPath> lstBackPath = new List<BackPath>();
                XmlDocument docCurrent = new System.Xml.XmlDocument();
                docCurrent.LoadXml(currentFlowNodeView.NodeXML);
                XmlNode preNode = docCurrent.SelectSingleNode("NodeXML/preCell/cellList");
                string[] preCellArr = preNode.InnerText.Split(',');
                foreach (string preCellCode in preCellArr)
                {
                    CompleteFlowNodeView selectCompleteFlowNodeView = backPassCodeList.SingleOrDefault(b => b.NodeCode == preCellCode);
                    if (selectCompleteFlowNodeView != null)
                    {
                        lstBackPath.Add(new BackPath() { PathStartNodeCode = selectCompleteFlowNodeView.NodeCode, PathEndNodeCode = currentFlowNodeView.NodeCode, OrderNo = lstBackPath.Count + 1, NodeType = selectCompleteFlowNodeView.NodeType });
                        AddBackPath(selectCompleteFlowNodeView.PreNodeCode, backPassCodeList, lstBackPath, selectCompleteFlowNodeView.NodeCode);
                    }
                }
                lstBackPath = lstBackPath.OrderByDescending(b => b.OrderNo).ToList();
                List<FlowGraphNodeView> addFlowGraphNodeViewList = FlowGraphNodeService.GetFlowGraphNode(model.RecordID);
                foreach (BackPath backPath in lstBackPath)
                {
                    int orderNo = 0;
                    FlowGraphNodeView firstFlowGraphNodeView = addFlowGraphNodeViewList.OrderByDescending(f => f.OrderNo).FirstOrDefault();
                    if (firstFlowGraphNodeView != null)
                    {
                        orderNo = firstFlowGraphNodeView.OrderNo;
                    }
                    addFlowGraphNodeViewList.Add(new FlowGraphNodeView()
                    {
                        ID = Guid.NewGuid(),
                        RecordID = model.RecordID,
                        PathStartNodeCode = backPath.PathStartNodeCode,
                        PathEndNodeCode = backPath.PathEndNodeCode,
                        OrderNo = orderNo + 1,
                        NodeType = backPath.NodeType,
                        ActionType = actionType
                    });
                }
                FlowGraphNodeService.AddFlowGraphNode(addFlowGraphNodeViewList);

                //回退之后再节点完成表里面有些数据需要清除
                //回退到的那个节点删除(不删它的子节点的理由:回退不是直接退到进入子流程之前的状态)
                //经过的节点删除经过节点以及经过节点的子流程节点
                //回退之后，那些要删除的节点以及它的or关系的并行节点的传阅、已阅和催办消息要删除
                List<CompleteFlowNodeView> deleteCompleteFlowNodeViewList = new List<CompleteFlowNodeView>();
                string flowCodeStr = "'" + model.CurrentFlowNodeCode + "',";
                foreach (CompleteFlowNodeView completeFlowNodeView in backPassCodeList)
                {
                    deleteCompleteFlowNodeViewList.Add(completeFlowNodeView);
                    if (completeFlowNodeView.NodeCode != backNodeCode)
                    {
                        flowCodeStr += "'" + completeFlowNodeView.NodeCode + "',";
                        GetOrBrotherNode(model.FlowCode, completeFlowNodeView.NodeCode, ref flowCodeStr);

                        AddSubDeleteCompleteFlowNode(model, completeFlowNodeView.NodeCode, deleteCompleteFlowNodeViewList, ref flowCodeStr);
                    }
                }
                CompleteFlowNodeService.DeleteCompleteFlowNode(deleteCompleteFlowNodeViewList);

                //获取当前节点的兄弟节点,因为这些节点的过程数据和消息也要删除
                string andCurrentNodeCodeStr = GetBrotherNodeCode(docCurrent, "NodeXML/brotherCell/andCellList");
                if (andCurrentNodeCodeStr != string.Empty)
                {
                    string[] andCurrentNodeCodeArr = andCurrentNodeCodeStr.Split(',');
                    foreach (string nodeCode in andCurrentNodeCodeArr)
                    {
                        flowCodeStr += "'" + nodeCode + "',";
                    }
                }
                string orCurrentNodeCodeStr = GetBrotherNodeCode(docCurrent, "NodeXML/brotherCell/orCellList");
                if (orCurrentNodeCodeStr != string.Empty)
                {
                    string[] orCurrentNodeCodeArr = orCurrentNodeCodeStr.Split(',');
                    foreach (string nodeCode in orCurrentNodeCodeArr)
                    {
                        flowCodeStr += "'" + nodeCode + "',";
                    }
                }
                flowCodeStr = flowCodeStr.TrimEnd(',');
                FlowProcessMessageService.ProcessFlowProcessMessageState(model.RecordID, flowCodeStr);

                //获取申请时间
                DateTime requestDate = GerRequestTime(model);

                //处理单据的业务数据
                ProcessReceiptForWithdraw(model.FlowCode, backFlowNodeView, model.RecordID, flowCodeStr);

                //添加待办
                int nodeLevel = Convert.ToInt32(selectBackNodeList[0].SelectSingleNode("NodeLevel").InnerText);
                AddBaklogTaskForBack(selectBackNodeList[0].SelectSingleNode("NodeProcessDepartmentPerson").InnerText, model, requestDate, backNodeCode, nodeLevel);
                string orNodeCodeStr = GetBrotherNodeCode(docBack, "NodeXML/brotherCell/orCellList");
                if (orNodeCodeStr != string.Empty)
                {
                    string[] brotherNodeCodeArr = orNodeCodeStr.Split(',');
                    foreach (string nodeCode in brotherNodeCodeArr)
                    {
                        FlowNodeView orBrotherFlowNodeView = FlowNodeService.GetFlowNodeByNodeCode(model.FlowCode, false, nodeCode);
                        string defaultProcessPerson = GetDefaultProcessPerson(orBrotherFlowNodeView.NodeXML, model.ProcessUserDepartment);
                        AddBaklogTaskForBack(defaultProcessPerson, model, requestDate, orBrotherFlowNodeView.NodeCode, orBrotherFlowNodeView.NodeLevel);
                    }
                }

                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }

        /// <summary>
        /// 添加已办、删除待办
        /// </summary>
        /// <param name="model">流转视图的Model</param>
        /// <param name="approvalOpinion">回退意见</param>
        /// <param name="currentFlowNodeView">当前节点</param>
        private void ProcessCurrentNodeForBack(FlowRecordView model, string approvalOpinion, FlowNodeView currentFlowNodeView)
        {
            List<ProcessedTaskView> addProcessedTaskList = new List<ProcessedTaskView>();
            List<BaklogTaskView> deleteBaklogTaskNewList = new List<BaklogTaskView>();
            List<BaklogTaskView> originalBaklogTaskList = BaklogTaskService.GetBaklogTaskByRecordID(model.RecordID);
            foreach (BaklogTaskView baklogTaskView in originalBaklogTaskList)
            {
                if (baklogTaskView.NodeLevel == currentFlowNodeView.NodeLevel)
                {
                    deleteBaklogTaskNewList.Add(baklogTaskView);
                    if (baklogTaskView.CurrentProcessPerson == User.Identity.Name)
                    {
                        addProcessedTaskList.Add(new ProcessedTaskView()
                        {
                            ID = Guid.NewGuid(),
                            RecordID = model.RecordID,
                            FlowCode = model.FlowCode,
                            CurrentProcessNodeCode = model.CurrentFlowNodeCode,
                            CurrentProcessNodeName = currentFlowNodeView.NodeName,
                            ApprovalOpinion = approvalOpinion,
                            CurrentProcessPersonDepartment = baklogTaskView.CurrentProcessPersonDepartment,
                            CurrentProcessPerson = baklogTaskView.CurrentProcessPerson,
                            ProcessTime = DateTime.Now,
                            HandleState = "4"
                        });
                    }
                }
            }
            ProcessedTaskService.AddProcessedTask(addProcessedTaskList);
            BaklogTaskService.DeleteBaklogTask(deleteBaklogTaskNewList);
        }

        private string GetBrotherNodeCode(XmlDocument doc, string path)
        {
            string brotherNodeStr = string.Empty;
            XmlNode brotherNode = doc.SelectSingleNode(path);
            if (brotherNode != null)
            {
                brotherNodeStr = brotherNode.InnerText;
            }
            return brotherNodeStr;
        }

        private int AddFlowProcessMessage(List<CompleteFlowNodeView> backPassCodeList, string flowCode, string backNodeCode)
        {
            int actionType = 1;
            if (backPassCodeList.Count > 1)
            {
                //发回退消息
                List<FlowProcessMessageView> flowProcessMessageAddViewList = new List<FlowProcessMessageView>();
                foreach (CompleteFlowNodeView completeFlowNodeView in backPassCodeList)
                {
                    if (completeFlowNodeView.NodeCode != backNodeCode)
                    {
                        string[] processDepartmentAndPersonArr = completeFlowNodeView.NodeProcessDepartmentPerson.Split(',');
                        foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
                        {
                            string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                            flowProcessMessageAddViewList.Add(new FlowProcessMessageView()
                            {
                                ID = GuidHelper.NewGuid(),
                                RecordID = completeFlowNodeView.RecordID,
                                FlowCode = flowCode,
                                FlowNodeCode = completeFlowNodeView.NodeCode,
                                ProcessUserDepartment = subProcessDepartmentAndPersonArr[0],
                                ProcessUser = subProcessDepartmentAndPersonArr[1],
                                SponsorUser = User.Identity.Name,
                                ProcessType = "4",
                                LastUpdateUser = User.Identity.Name
                            });
                        }
                    }
                }
                FlowProcessMessageService.AddFlowProcessMessage(flowProcessMessageAddViewList);
                actionType = 2;
            }
            return actionType;
        }

        private void AddBackPath(string preNodeCodeStr, List<CompleteFlowNodeView> backPassCodeList, List<BackPath> lstBackPath, string nodeCode)
        {
            if (!string.IsNullOrEmpty(preNodeCodeStr))
            {
                string[] preNodeCodeArr = preNodeCodeStr.Split(',');
                foreach (string preNodeCode in preNodeCodeArr)
                {
                    CompleteFlowNodeView selectCompleteFlowNodeView = backPassCodeList.SingleOrDefault(b => b.NodeCode == preNodeCode);
                    if (selectCompleteFlowNodeView != null)
                    {
                        lstBackPath.Add(new BackPath() { PathStartNodeCode = selectCompleteFlowNodeView.NodeCode, PathEndNodeCode = nodeCode, OrderNo = lstBackPath.Count + 1, NodeType = selectCompleteFlowNodeView.NodeType });
                        AddBackPath(selectCompleteFlowNodeView.PreNodeCode, backPassCodeList, lstBackPath, selectCompleteFlowNodeView.NodeCode);
                    }
                }
            }
        }

        private void GetOrBrotherNode(string flowCode, string nodeCode, ref string flowCodeStr)
        {
            FlowNodeView flowNodeView = FlowNodeService.GetFlowNodeByNodeCode(flowCode, false, nodeCode);
            XmlDocument doc = new System.Xml.XmlDocument();
            doc.LoadXml(flowNodeView.NodeXML);
            XmlNode orBrotherNode = doc.SelectSingleNode("NodeXML/brotherCell/orCellList");
            if (orBrotherNode != null)
            {
                string[] orBrotherNodeArr = orBrotherNode.InnerText.Split(',');
                foreach (string orBrotherNodeCode in orBrotherNodeArr)
                {
                    flowCodeStr += "'" + orBrotherNodeCode + "',";
                }
            }
        }

        private void AddSubDeleteCompleteFlowNode(FlowRecordView model, string parentNodeCode, List<CompleteFlowNodeView> deleteCompleteFlowNodeViewList, ref string flowCodeStr)
        {
            List<CompleteFlowNodeView> subCompleteFlowNodeViewList = CompleteFlowNodeService.GetCompleteFlowNodeByParentNodeCode(model.RecordID, parentNodeCode, false, true);
            foreach (CompleteFlowNodeView subCompleteFlowNodeView in subCompleteFlowNodeViewList)
            {
                deleteCompleteFlowNodeViewList.Add(subCompleteFlowNodeView);
                flowCodeStr += "'" + subCompleteFlowNodeView.NodeCode + "',";
                GetOrBrotherNode(model.FlowCode, subCompleteFlowNodeView.NodeCode, ref flowCodeStr);
                AddSubDeleteCompleteFlowNode(model, subCompleteFlowNodeView.NodeCode, deleteCompleteFlowNodeViewList, ref flowCodeStr);
            }
        }

        private DateTime GerRequestTime(FlowRecordView model)
        {
            if (model.FlowCode == "Alter")
            {
                return AlterService.GetAlterByID(model.RecordID).RequestDate;
            }
            else if (model.FlowCode == "AlterOrderOne" || model.FlowCode == "AlterOrderTwo" || model.FlowCode == "AlterOrderThree")
            {
                return AlterOrderService.GetAlterOrderByID(model.RecordID).RequestDate;
            }
            else if (model.FlowCode == "TotalMaintenance")
            {
                return TotalMaintenanceService.GetTotalMaintenanceByID(model.RecordID.ToGuid()).RequestDate;
            }
            else if (model.FlowCode == "YearPlan")
            {
                return YearPlanService.GetYearPlanByID(model.RecordID.ToGuid()).RequestDate;
            }
            else if (model.FlowCode == "MonthPlan")
            {
                return MonthPlanService.GetMonthPlanByID(model.RecordID.ToGuid()).RequestDate;
            }
            else if (model.FlowCode == "StageSchedule")
            {
                return StageScheduleService.GetStageScheduleByID(model.RecordID.ToGuid()).RequestDate;
            }
            else if (model.FlowCode == "EngineeringImageSchedule")
            {
                return EngineeringImageScheduleService.GetEngineeringImageScheduleByID(model.RecordID.ToGuid()).RequestDate;
            }
            else
            {
                return DateTime.Now;
            }
        }

        private void ProcessReceiptForWithdraw(string flowCode, FlowNodeView flowNodeView, string recordID, string nodeCodeStr)
        {
            switch (flowCode)
            {
                case "AlterOne":
                case "AlterTwo":
                case "AlterThree":
                    if (flowNodeView.NodeType == 1)
                    {
                        AlterService.WithdrawOrBackAlterForRequestNode(recordID, flowNodeView.NodeCode);
                    }
                    else
                    {
                        AlterService.WithdrawOrBackAlterForOtherNode(recordID, flowNodeView.NodeCode, nodeCodeStr);
                        //取最后一个发送的节点作为业务数据
                        AlterView alterView = AlterService.GetAlterBackupByAlterID(recordID);
                        List<AlterBillView> lstAlterBillView = AlterService.GetAlterBillBackupList(alterView.AlterID, alterView.AssociatedNodeCode, alterView.LastUpdateUserDepartment, alterView.LastUpdateUser);
                        AlterService.SaveAlter(alterView, lstAlterBillView);
                    }
                    break;
                case "AlterOrderOne":
                    if (flowNodeView.NodeType == 1)
                    {
                        AlterOrderService.WithdrawOrBackAlterOrderForRequestNode(recordID, flowNodeView.NodeCode);
                    }
                    else
                    {
                        AlterOrderService.WithdrawOrBackAlterOrderForOtherNode(recordID, flowNodeView.NodeCode, nodeCodeStr);
                        //取最后一个发送的节点作为业务数据
                        AlterOrderView alterOrderView = AlterOrderService.GetAlterOrderBackupByAlterOrderID(recordID);
                        List<AlterOrderBillView> lstAlterOrderBillView = AlterOrderService.GetAlterOrderBillBackupList(alterOrderView.AlterOrderID, alterOrderView.AssociatedNodeCode, alterOrderView.LastUpdateUserDepartment, alterOrderView.LastUpdateUser);
                        AlterOrderService.SaveAlterOrder(alterOrderView, lstAlterOrderBillView);
                    }
                    break;
                case "Expense":
                    if (flowNodeView.NodeType == 1)
                    {
                        ExpenseService.WithdrawOrBackExpenseForRequestNode(recordID, flowNodeView.NodeCode);
                    }
                    else
                    {
                        ExpenseService.WithdrawOrBackExpenseForOtherNode(recordID, flowNodeView.NodeCode, nodeCodeStr);
                        //取最后一个发送的节点作为业务数据
                        ExpenseView expenseView = ExpenseService.GetExpenseBackupByExpenseID(recordID);
                        List<ConstructionContractEepenseBillView> saveList = new List<ConstructionContractEepenseBillView>();
                        if (expenseView.ContractSource == "Construction")
                        {
                            saveList = ExpenseService.GetBillBackupList(expenseView.ExpenseID, expenseView.AssociatedNodeCode, expenseView.LastUpdateUserDepartment, expenseView.LastUpdateUser);
                        }
                        ExpenseService.SaveExpense(expenseView, saveList);
                    }
                    break;
            }
        }

        /// <summary>
        /// 添加回退待办
        /// </summary>
        /// <param name="selectBackNodeList">回退节点信息</param>
        /// <param name="model">流转视图的Model</param>
        /// <param name="requestPerson">申请人</param>
        /// <param name="backNodeCode">回退节点</param>
        private void AddBaklogTaskForBack(string nodeProcessDepartmentPerson, FlowRecordView model, DateTime requestDate, string backNodeCode, int nodeLevel)
        {
            List<BaklogTaskView> addList = new List<BaklogTaskView>();
            string[] processDepartmentAndPersonArr = nodeProcessDepartmentPerson.Split(',');
            foreach (string processDepartmentAndPerson in processDepartmentAndPersonArr)
            {
                string[] subProcessDepartmentAndPersonArr = processDepartmentAndPerson.Split('|');
                BaklogTaskView add = new BaklogTaskView();
                add.ID = GuidHelper.NewGuid();
                add.RecordID = model.RecordID;
                add.TaskType = model.FlowCode;
                add.RequestDate = requestDate;
                add.CurrentFlowNodeCode = backNodeCode;
                add.CurrentProcessPersonDepartment = subProcessDepartmentAndPersonArr[0];
                add.CurrentProcessPerson = subProcessDepartmentAndPersonArr[1];
                add.NodeLevel = nodeLevel;
                addList.Add(add);
            }
            BaklogTaskService.AddBaklogTask(addList);
        }
        #endregion

        #region 反审核
        public ActionResult ExpenseReverseAudit()
        {
            try
            {
                //此处这些参数写死，因为节点名称、用户名和部门基本不会改。如果改了，流程也得改
                string expenseID = Request["expenseID"];
                string flowNodeCode = "GCYLKKZ";
                string userName = "baiq";
                string department = "chugongchengyangguanke";

                //更新单据状态
                ExpenseView expenseView = ExpenseService.GetExpenseBackupByCondition(expenseID, flowNodeCode, department, userName);
                expenseView.HandleState = "1";
                expenseView.SendState = "0";
                expenseView.LastUpdateTime = DateTime.Now;

                List<ConstructionContractEepenseBillView> saveList = new List<ConstructionContractEepenseBillView>();
                if (expenseView.ContractSource == "Construction")
                {
                    List<ConstructionContractEepenseBillView> lstConstructionContractEepenseBillView = ExpenseService.GetBillBackupList(Guid.Parse(expenseID), flowNodeCode, department, userName);
                    foreach (ConstructionContractEepenseBillView constructionContractEepenseBillView in lstConstructionContractEepenseBillView)
                    {
                        constructionContractEepenseBillView.SendState = "1";
                        constructionContractEepenseBillView.LastUpdateTime = DateTime.Now;
                        saveList.Add(constructionContractEepenseBillView);
                    }
                }
                ExpenseService.SaveExpenseBackup(expenseView, saveList);
                ExpenseService.SaveExpense(expenseView, saveList);

                //删除流程数据
                ExpenseService.ReverseAudit(expenseID, flowNodeCode, userName);

                //添加代办
                List<BaklogTaskView> addList = new List<BaklogTaskView>();
                BaklogTaskView add = new BaklogTaskView();
                add.ID = GuidHelper.NewGuid();
                add.RecordID = expenseID;
                add.TaskType = "Expense";
                add.RequestDate = expenseView.RequestDate;
                add.CurrentFlowNodeCode = flowNodeCode;
                add.CurrentProcessPersonDepartment = department;
                add.CurrentProcessPerson = userName;
                add.NodeLevel = 1;
                addList.Add(add);
                BaklogTaskService.AddBaklogTask(addList);

                return Content("Success");
            }
            catch (Exception ex)
            {
                return Content(ex.Message);
            }
        }
        #endregion
    }

    public class BackPath
    {
        public string PathStartNodeCode { get; set; }

        public string PathEndNodeCode { get; set; }

        public int OrderNo { get; set; }

        public int NodeType { get; set; }
    }
}